package com.virtualCat.service.impl;

import com.virtualCat.common.Msg;
import com.virtualCat.common.WeChatConfig;
import com.virtualCat.dao.CatDao;
import com.virtualCat.dao.FeedDao;
import com.virtualCat.dao.OrderDao;
import com.virtualCat.dao.UserDao;
import com.virtualCat.entity.*;
import com.virtualCat.service.FeedService;
import com.virtualCat.util.WeChatPayUtil;
import com.virtualCat.vo.UserInfo;
import com.virtualCat.vo.WeixinBackInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class FeedServiceImpl implements FeedService {
    @Autowired
    private FeedDao feedDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private CatDao catDao;
    @Autowired
    private OrderDao orderDao;

    private ObjectMapper mapper = new ObjectMapper();

    private static org.slf4j.Logger log = LoggerFactory.getLogger(FeedServiceImpl.class);

    /**
     * 登陆
     */
    public Msg login(String code) {
        String jsonText= WeChatPayUtil.wechatCode(code);
        log.info("返回值:"+jsonText);
        System.out.println(jsonText);
        if(jsonText.contains("errcode")){
            log.info("授权失败:"+jsonText);
            return Msg.fail().add("errCode",40029).add("errMsg","无效的code");
        }else{//初始化用户
            log.info("成功："+jsonText);
            WeixinBackInfo weixinBackInfo = null;
            try {
                log.info("json转Object开始");
                weixinBackInfo = mapper.readValue(jsonText, WeixinBackInfo.class);
                log.info("json转Object结束");
            } catch (IOException e) {
                e.printStackTrace();
            }
            String openid=weixinBackInfo.getOpenid();
            log.info("openid:"+openid);
            if (userDao.findByOpenid(openid)!=null){
                return Msg.success().add("openid",openid).add("status",1);
            }else{
                User user=new User();
                user.setOpenid(weixinBackInfo.getOpenid());
                if(weixinBackInfo.getUnionid()!=null){
                    user.setUnionid(weixinBackInfo.getUnionid());
                }
                user.setObtain(new Date());
                user.setCat_food(5);
                userDao.insertUser(user);
                return Msg.success().add("openid",openid).add("status",0);
            }
        }
    }

    /**
     * 添加新用户的信息
     * @param userInfo
     * @return
     */
    public Msg createUser(UserInfo userInfo){
        if(StringUtils.isNotBlank(userInfo.getOpenid())){
            User user=userDao.findByOpenid(userInfo.getOpenid());
            log.info("user_info:"+userInfo);
            if (user == null){
                return Msg.fail().add("用户不存在","10102");
            }
            log.info("======用户存在=====");
            user.setNickName(userInfo.getNickName());
            user.setImgUrl(userInfo.getAvatarUrl());
            user.setSex(userInfo.getGender());
            user.setHistory(0);
            int resultCount = userDao.updateInfo(user);
            if (resultCount > 0){
                return Msg.success();
            }
            return Msg.fail().add("添加用户信息失败","10103");
        }else{
            return Msg.fail().add("openid为空","10101");
        }
    }

    /**
     * 首页
     * @param openid
     * @return
     */
    public Msg raiseCat(String openid) {
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",10201);
        }
        User user=userDao.findByOpenid(openid);
        userDao.updateLoginTime(new Date(),openid);
        Map<String,String> feedData = null;
        Map<String,String> userData = null;
        Feed feed=feedDao.findByOpenid(openid);
        if (feed == null){
            return Msg.fail().add("feed_info not found",10202);
        }
        Cat cat=catDao.findById(feed.getCatid());
        if (cat == null){
            return Msg.fail().add("cat not found",10203);
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        if (!formatter.format(user.getObtain()).equals(formatter.format(new Date()))){
            feed.setFeedCount(0);
            feed.setDiscover(0);
            feed.setShareCount(0);
            feed.setFeedCount(0);
            feedDao.updateFeed(feed);
        }
        Map<String,String> catData = new HashMap<String, String>();
        catData.put("openid",openid);
        catData.put("cat_name",cat.getCname());
        catData.put("cat_img", WeChatConfig.PIC_RESOURCES_PREFIX_PATH+cat.getCimg());
        catData.put("cat_desc",cat.getCdesc());
        catData.put("good_name",cat.getGname());
        catData.put("original_price",String.valueOf(cat.getOprice()));
        catData.put("detail",cat.getDetail());
        feedData = new HashMap<String, String>();
        feedData.put("growth",String.valueOf(feed.getGrowth()));
        feedData.put("food",String.valueOf(user.getCat_food()));
        userData = new HashMap<String, String>();
        userData.put("nickname",user.getNickName());
        userData.put("img_url",user.getImgUrl());
        userData.put("history",String.valueOf(user.getHistory()));
        userData.put("good_img",WeChatConfig.PIC_RESOURCES_PREFIX_PATH+cat.getGimg());
        return Msg.success().add("cat_info",catData)
                .add("feed_info",feedData).add("user_info",userData);
    }

    /**
     * 喂养猫咪
     * @param
     * @return
     */
    public Msg feedCat(String openid){
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",10301);
        }
        Feed feed=feedDao.findByOpenid(openid);
        if (feed == null){
            return Msg.fail().add("没有喂养猫咪信息",10302);
        }
        int catFood = userDao.selectFoodByopenid(openid);
        if (catFood == 0){
            return Msg.fail().add("没有猫粮了",10307);
        }
        if (feed.getFeedCount() == 2){
            return Msg.fail().add("次数已满",10303);
        }
        Date nowTime = new Date();
        long s = (nowTime.getTime() - feed.getFeedTime().getTime()) / 1000;
        if ((s / 3600) <= 2){
            return Msg.fail().add("喂食冷却中",10304);
        }
        if(feed.getGrowth()==100){
            return Msg.fail().add("成长值已满",10305);
        }
        int growth = feed.getGrowth();
        if (growth > 95){
            growth = 100;
        }else{
            growth +=5;
        }
        feed.setGrowth(growth);
        feed.setFeedTime(nowTime);
        feed.setFeedCount(feed.getFeedCount()+1);
        if (catFood-1 == 0){
            userDao.updateFoodByopenid(0,openid);
        }else{
            userDao.updateFoodByopenid(catFood-1 ,openid);
        }
        resultCount = feedDao.updateFeed(feed);
        if (resultCount < 1){
            return Msg.fail().add("更新数据异常",10306);
        }
        return  Msg.success();
    }

    /**
     * 寻找猫粮
     * @param openid
     * @return
     */
    public Msg discoverFood(String openid) {
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",10401);
        }
        Feed feed = feedDao.findByOpenid(openid);
        if(feed == null){
            return Msg.fail().add("喂养信息异常丢失",10402);
        }
        int count = feed.getDiscover();
        if(count < 10){
            feed.setDiscover(count+1);
            int catFood = userDao.selectFoodByopenid(openid);
            userDao.updateFoodByopenid(catFood+1,openid);
            feedDao.updateFeed(feed);
            return Msg.success().add("found_count",feed.getDiscover());
        }else{
            return Msg.fail().add("达到今日上限",10403);
        }
    }

    /**
     * 获得喵咪信息
     * @return 喵咪信息列表
     */
    public Msg catList(){
        List<Cat> cats=catDao.findAll();
        if (cats!=null&&!cats.isEmpty()){
            for(Cat cat : cats){
                cat.setCimg(WeChatConfig.PIC_RESOURCES_PREFIX_PATH+cat.getCimg());
                cat.setGimg(WeChatConfig.PIC_RESOURCES_PREFIX_PATH+cat.getGimg());
            }
            return Msg.success().add("cat_list",cats);
        }
        return Msg.fail().add("信息为空",10501);
    }

    /**
     * 检测猫咪是否存在
     * @param openid
     * @return
     */
    public Msg checkCat(String openid) {
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",11001);
        }
        resultCount = feedDao.checkByOpenid(openid);
        if (resultCount > 0){
            return Msg.fail().add("已有猫咪，不允许购买",11002);
        }
        return Msg.success();
    }

    /**
     * 猫咪兑换
     * @param openid
     * @return
     */
    @Transactional
    public Msg exchange(String openid) {
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",10601);
        }
        Feed feed=feedDao.findByOpenid(openid);
        if(feed == null){
            return Msg.fail().add("无喂养信息",10602);
        }
        User user=userDao.findByOpenid(openid);
        Cat cat=catDao.findById(feed.getCatid());
        if(cat == null){
            return Msg.fail().add("猫咪信息不存在",10603);
        }
        Order order=new Order(UUID.randomUUID().toString().replaceAll("-", ""),openid,cat.getCatid(),new Date(),
                cat.getNprice(),user.getReceiver(),user.getPhone(),user.getArea(),user.getBuild_number(),cat.getCname(),
                cat.getGname(),cat.getGimg(),0);
        resultCount = orderDao.insertOrder(order);
        if (resultCount == 0){
            return Msg.fail().add("订单生成失败",10604);
        }
        userDao.updateHistory(openid,user.getHistory()+1);
        feedDao.deleteFeed(openid);
        return Msg.success();
    }

    /**
     * 获取确认地址
     */
    public Msg gainAddress(String openid){
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",10801);
        }
        User user=userDao.findByOpenid(openid);
        Map<String,String> addressData =new HashMap<String,String>();
        addressData.put("receiver",user.getReceiver());
        addressData.put("phone",user.getPhone());
        addressData.put("area",user.getArea());
        addressData.put("build_number",user.getBuild_number());
        return Msg.success().add("user_address",addressData);
    }


    /**
     * 抛弃猫咪
     * @param openid
     * @return 返回删除结果
     */
    public Msg throwCat(String openid){
        int resultCount = userDao.selectUserByOpenid(openid);
        if (resultCount < 0){
            return Msg.fail().add("用户不存在",10701);
        }
        resultCount = feedDao.deleteFeed(openid);
        if (resultCount == 0)
            return Msg.fail().add("删除失败",10702);
        return Msg.success();
    }

    /**
     * 获取二维码
     * @param sceneStr
     * @param accessToken
     * @return
     */
    public String getminiqrQr(String sceneStr, String accessToken) {
        RestTemplate rest = new RestTemplate();
        InputStream inputStream = null;
        String path = null;
        try {
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
            Map<String, Object> param = new HashMap<String,Object>();
            param.put("scene", "activity_" + sceneStr);
            param.put("page", "pages/Activity/Situation/Situation");
            param.put("width", 200);
            log.info("调用生成微信URL接口传参：" + param);

            MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
            org.springframework.http.HttpEntity requestEntity = new org.springframework.http.HttpEntity(param, headers);
            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class);
            log.info("调用小程序生成微信小程序码URL接口返回结果：" + entity.getBody());

            byte[] result = entity.getBody();
            log.info(Base64Utils.encodeToString(result));
            inputStream = new ByteArrayInputStream(result);

//            //七牛上传
//            path = qiniuService.uploadByStream(inputStream);
//            logger.info("----------------path：{}", path);

        } catch (Exception e) {
            log.error("调用小程序生成微信小程序码URL接口异常", e);

        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return path;
    }

    /**
     * 分享页面
     * @param user_openid
     * @param share_openid
     * @return
     */
    public Msg share(String user_openid,String share_openid){
        User user = userDao.findByOpenid(user_openid);
        if (user == null){
            return Msg.fail().add("用户不存在",11401);
        }
        int cat_food  = userDao.selectFoodByopenid(share_openid);
        Feed feed=feedDao.findByOpenid(user_openid);
        if (feed == null){
            return Msg.fail().add("feed_info not found",11402);
        }
        Cat cat=catDao.findById(feed.getCatid());
        if (cat == null){
            return Msg.fail().add("cat not found",11403);
        }
        Map<String,String> userData = new HashMap<String, String>();
        userData.put("cat_name",cat.getCname());
        userData.put("cat_desc",cat.getCdesc());
        userData.put("cat_img",WeChatConfig.PIC_RESOURCES_PREFIX_PATH+cat.getCimg());
        userData.put("good_desc",cat.getGdesc());
        userData.put("user_img",user.getImgUrl());
        userData.put("good_img",WeChatConfig.PIC_RESOURCES_PREFIX_PATH+cat.getGimg());
        userData.put("good_price",String.valueOf(cat.getNprice()));
        userData.put("good_name",cat.getCname());
        userData.put("growth",String.valueOf(feed.getGrowth()));
        userData.put("good_detail",cat.getDetail());
        return Msg.success().add("userData",userData).add("cat_food",cat_food);
    }

    /**
     * 分享喂养
     * @param user_openid
     * @param share_openid
     * @param cardDate
     * @return
     */
    public Msg shareRaise(String user_openid,String share_openid,Date cardDate){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        if (!formatter.format(cardDate).equals(formatter.format(new Date()))){
            return Msg.fail().add("卡片过期",11501);
        }
        int cat_food  = userDao.selectFoodByopenid(share_openid);
        if (cat_food == 0){
            return Msg.fail().add("喂养者没有猫粮",11502);
        }
        Feed feed=feedDao.findByOpenid(user_openid);
        if (feed == null){
            return Msg.fail().add("feed_info not found",11502);
        }
        Cat cat=catDao.findById(feed.getCatid());
        if (cat == null){
            return Msg.fail().add("cat not found",11503);
        }
        if(feed.getGrowth()==100){
            return Msg.fail().add("成长值已满",11504);
        }
        int growth = feed.getGrowth();
        if (growth > 95){
            growth = 100;
        }else{
            growth +=5;
        }
        int rowCount = feedDao.updateGrowthByOpenid(growth,user_openid);
        if (rowCount == 0){
            return Msg.fail().add("喂养失败",11505);
        }
        if (cat_food-1 == 0){
            userDao.updateFoodByopenid(0,share_openid);
        }else{
            userDao.updateFoodByopenid(cat_food-1,share_openid);
        }
        return Msg.success();
    }
}
